package jnpf.engine.custom.helper;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.ImmutableList;
import jnpf.base.ActionResult;
import jnpf.engine.assembly.UserTaskExPropertyDTO;
import jnpf.engine.assembly.prop.UserTaskAdvancedSettingDTO;
import jnpf.engine.assembly.prop.UserTaskBasicPropDTO;
import jnpf.engine.custom.constants.BasicActivitiConstants;
import jnpf.engine.custom.constants.GlobalProcessVariableConstants;
import jnpf.engine.custom.variables.entity.FormDataInfo;
import jnpf.engine.entity.*;
import jnpf.engine.enums.*;
import jnpf.engine.model.FlowTaskOperatorRecordDTO;
import jnpf.engine.model.flowengine.FlowModel;
import jnpf.engine.model.flowengine.shuntjson.childnode.Properties;
import jnpf.engine.service.FlowDelegateService;
import jnpf.engine.service.FlowTaskOperatorRecordService;
import jnpf.engine.util.FlowContextHolder;
import jnpf.engine.util.FlowMsgUtil;
import jnpf.engine.util.SpringContextHolder;
import jnpf.permission.entity.OrganizeEntity;
import jnpf.permission.entity.UserEntity;
import jnpf.permission.entity.UserRelationEntity;
import jnpf.permission.service.OrganizeService;
import jnpf.permission.service.UserRelationService;
import jnpf.permission.service.UserService;
import jnpf.util.*;
import jnpf.util.wxutil.HttpUtil;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.*;
import org.flowable.bpmn.model.Process;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static jnpf.engine.custom.constants.GlobalProcessVariableConstants.*;
import static jnpf.engine.util.BpmnModelUtils.*;
import static jnpf.engine.util.BpmnModelUtils.getFirstNodeProperty;

/**
 * @Date:Created in 2022/4/17 11:30
 */
@Component
public class UserTaskNodeHelper {

    @Resource
    private UserRelationService userRelationService;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private FlowDelegateService flowDelegateService;
    @Resource
    private UserService userService;
    @Resource
    private OrganizeService organizeService;
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private HistoryService historyService;

    @Resource
    private ServiceAllUtil serviceAllUtil;
    /**
     * 节点id
     **/
    private String taskNodeId = "taskNodeId";
    /**
     * 状态
     **/
    private String handleStatus = "handleStatus";
    /**
     * 任务id
     **/
    private String taskId = "taskId";

    /**
     *
     * @param userTaskExPropertyDTO 扩展属性
     * @param task
     * @param flowId
     * @return
     */
    /**
     * 递归上级部门
     *
     * @param
     * @return
     * @copyright 引迈信息技术有限公司
     * @date 2022/6/29
     */
    private OrganizeEntity getManageOrgByLevel(String organizeId, long level) {
        --level;
        if (level == 0) {
            return serviceAllUtil.getOrganizeInfo(organizeId);
        } else {
            OrganizeEntity organizeInfo = serviceAllUtil.getOrganizeInfo(organizeId);
            return organizeInfo != null ? getManageOrgByLevel(organizeInfo.getParentId(), level) : null;
        }
    }
    public   List<String> getAssignUserList(Properties properties, Map<String,String> taskInfoMap, String flowId,Map<String,Object> formDataMap) {
        String processDefinitionId = MapUtil.getStr(taskInfoMap, "processDefinitionId");
        String taskDefinitionKey = MapUtil.getStr(taskInfoMap, "taskDefinitionKey");
        String processInstanceId = MapUtil.getStr(taskInfoMap, "processInstanceId");
        String businessKey = MapUtil.getStr(taskInfoMap, BUSINESS_KEY);
        String applyUserId = MapUtil.getStr(taskInfoMap, APPLY_USER_ID);
        List<String> userIds=new ArrayList<>();
        Process bpmnModelMainProcess = getBpmnModelMainProcess(processDefinitionId);
        FlowElement flowElement = bpmnModelMainProcess.getFlowElement(taskDefinitionKey);
        Integer assigneeType=FlowTaskOperatorEnum.InitiatorMe.getCode();
        if(flowElement instanceof CallActivity || flowElement instanceof ManualTask){
            assigneeType=properties.getInitiateType();
        }
        else{
            assigneeType = properties.getAssigneeType();
        }
        //发起者【发起者主管】
        if (FlowTaskOperatorEnum.LaunchCharge.getCode().equals(assigneeType)) {
            UserEntity info = serviceAllUtil.getUserInfo(applyUserId);
            if (info != null) {
                userIds.add(getManagerByLevel(info.getManagerId(), properties.getManagerLevel()));
            }
        }
        else if (FlowTaskOperatorEnum.ContinueLaunchCharge.getCode().equals(assigneeType)) {
            UserEntity info = serviceAllUtil.getUserInfo(applyUserId);
            List<String> levelList = new LinkedList<>();
            if (info != null) {
                getManagerContinueByLevel(info.getManagerId(), properties.getManagerLevel(),levelList);
//                userIds.addAll(levelList);
                //true 自上而下   false  自下而上??
                if(CollUtil.isNotEmpty(levelList)){
                    Boolean orderFlag = properties.getOrderFlag();
                    if(Boolean.TRUE.equals(orderFlag)){
                        List<String> reverse = CollUtil.reverse(levelList);
                        userIds.addAll(reverse);
                    }
                    else{
                        //
                        userIds.addAll(levelList);
                    }
                }
            }
        }
        //发起者【部门主管】
        else if (FlowTaskOperatorEnum.DepartmentCharge.getCode().equals(assigneeType)) {
            UserEntity userEntity = serviceAllUtil.getUserInfo(applyUserId);
            if (userEntity != null) {
                OrganizeEntity organizeEntity = getManageOrgByLevel(userEntity.getOrganizeId(), properties.getDepartmentLevel());
                if (organizeEntity != null && StringUtil.isNotEmpty(organizeEntity.getManagerId())) {
                    List<String> list = Arrays.asList(organizeEntity.getManagerId().split(","));
                    userIds.addAll(list);
                }
            }
        }
        //发起者【分管领导】
        else if (FlowTaskOperatorEnum.ResponsibleLeader.getCode().equals(assigneeType)) {
            UserEntity userEntity = serviceAllUtil.getUserInfo(applyUserId);
            if (userEntity != null) {
                OrganizeEntity organizeEntity = getManageOrgByLevel(userEntity.getOrganizeId(), properties.getDepartmentLevel());
                if (organizeEntity != null && StringUtil.isNotEmpty(organizeEntity.getResponsibleLeaderId())) {
                    List<String> list = Arrays.asList(organizeEntity.getResponsibleLeaderId().split(","));
                    userIds.addAll(list);
                }
            }
        }

        //发起者【直属领导】
        else if (FlowTaskOperatorEnum.DirectSupervisor.getCode().equals(assigneeType)) {
            UserEntity userEntity = serviceAllUtil.getUserInfo(applyUserId);
            if (userEntity != null) {
                OrganizeEntity organizeEntity = getManageOrgByLevel(userEntity.getOrganizeId(), properties.getDepartmentLevel());
                if (organizeEntity != null && StringUtil.isNotEmpty(organizeEntity.getDirectSupervisorId())) {
                    List<String> list = Arrays.asList(organizeEntity.getDirectSupervisorId().split(","));
                    userIds.addAll(list);
                }
            }
        }

        else if (FlowTaskOperatorEnum.ContinueDepartmentCharge.getCode().equals(assigneeType)) {
            UserEntity userEntity = serviceAllUtil.getUserInfo(applyUserId);
            List<String> deptList=new LinkedList<>();
            if (userEntity != null) {
                String breakFlag="2";//1退出 2,不退出
                getManageOrgContinueByLevel(userEntity.getOrganizeId(), properties.getDepartmentLevel(),deptList,properties.getNoLeaderFlag(),breakFlag);
                if(CollUtil.isNotEmpty(deptList)){
                    Boolean orderFlag = properties.getOrderFlag();
                    if(Boolean.TRUE.equals(orderFlag)){
                        List<String> reverse = CollUtil.reverse(deptList);
                        userIds.addAll(reverse);
                    }
                    else{
                        //
                        userIds.addAll(deptList);
                    }
                }
            }
        }
        else if(FlowTaskOperatorEnum.MultipleDeptLeader.getCode().equals(assigneeType)){
            List<String> deptIds = properties.getDeptIds();
            Set<String> sets= new HashSet<>(deptIds);
            List<String> multipleIds=new ArrayList<>();
            List<OrganizeEntity> orgEntityList = organizeService.getOrgEntityList(sets);
            if(CollUtil.isNotEmpty(orgEntityList)){
                for (OrganizeEntity organizeEntity : orgEntityList) {
                    String managerId = organizeEntity.getManagerId();
                    multipleIds.add(managerId);
                }
                userIds.addAll(multipleIds);
            }
        }
        //【发起本人】
        else if (FlowTaskOperatorEnum.InitiatorMe.getCode().equals(assigneeType)) {
            userIds.add(applyUserId);
        }
        //【环节】
        else if (FlowTaskOperatorEnum.Tache.getCode().equals(assigneeType)) {
            //此有歧义 留给后续产品经理探讨
            String nodeId = properties.getNodeId();
            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
            Process mainProcess = bpmnModel.getMainProcess();
            UserTask targetNode = (UserTask) bpmnModel.getFlowElement(nodeId);
            String property = getAttributeValueByTaskDefinitionKey(mainProcess, targetNode.getId(), "userTask");
            Properties targetNodeProperty = JSONObject.parseObject(property, new TypeReference<Properties>() {
            });
            taskInfoMap.put("taskDefinitionKey",targetNode.getId());
            List<String> assignUserList = getAssignUserList(targetNodeProperty, taskInfoMap, flowId,formDataMap);
            userIds.addAll(assignUserList);
        }
        //【变量】
        else if (FlowTaskOperatorEnum.Variate.getCode().equals(assigneeType)) {
            //获取到节点上的数据传递

            Object data = formDataMap.get(properties.getFormField());
            if (data != null) {
                List<String> list = new ArrayList<>();
                try {
                    list.addAll(JsonUtil.getJsonToList(String.valueOf(data), String.class));
                } catch (Exception e) {

                }
                if (data instanceof List) {
                    list.addAll((List) data);
                } else {
                    list.addAll(Arrays.asList(String.valueOf(data).split(",")));
                }
                List<String> id = new ArrayList<>();
                for (String s : list) {
                    id.add(s.split("--")[0]);
                }
                List<UserRelationEntity> listByObjectIdAll = serviceAllUtil.getListByObjectIdAll(id);
                List<String> userPosition = listByObjectIdAll.stream().map(UserRelationEntity::getUserId).collect(Collectors.toList());
                List<String> handleIdAll = new ArrayList<>();
                handleIdAll.addAll(userPosition);
                handleIdAll.addAll(id);
                userIds.addAll(handleIdAll);
            }
        }
        //【服务】
        else if (FlowTaskOperatorEnum.Serve.getCode().equals(assigneeType)) {
            FlowTaskOperatorRecordService flowTaskOperatorRecordService = SpringContextHolder.getBean(FlowTaskOperatorRecordService.class);
            LambdaQueryWrapper<FlowTaskOperatorRecordEntity> flowTaskOperatorRecordEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
            flowTaskOperatorRecordEntityLambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getTaskId,processInstanceId);
            UserTask firstNode = getFirstNode(bpmnModelMainProcess);
            flowTaskOperatorRecordEntityLambdaQueryWrapper.eq(FlowTaskOperatorRecordEntity::getNodeCode,firstNode.getId());
            FlowTaskOperatorRecordEntity flowTaskOperatorRecordEntity = flowTaskOperatorRecordService.list(flowTaskOperatorRecordEntityLambdaQueryWrapper).get(0);
            FlowModel flowModel = new FlowModel();
            flowModel.setFormData(formDataMap);
            FlowTaskOperatorRecordDTO flowTaskOperatorRecordDTO = new FlowTaskOperatorRecordDTO();
            flowTaskOperatorRecordDTO.setAssignee(flowTaskOperatorRecordEntity.getHandleId());
            flowTaskOperatorRecordDTO.setProcessInstanceId(flowTaskOperatorRecordEntity.getTaskId());
            flowTaskOperatorRecordDTO.setTaskId(flowTaskOperatorRecordEntity.getTaskNodeId());
            properties.getInterfaceConfig().setOn(Boolean.TRUE);
            FlowMsgUtil flowMsgUtil = SpringContextHolder.getBean(FlowMsgUtil.class);
            ActionResult result = flowMsgUtil.event(13, properties, flowTaskOperatorRecordDTO, flowModel, bpmnModelMainProcess, taskDefinitionKey);
            if (Objects.equals(200, result.getCode())) {
                Object data = result.getData();
                if (data instanceof Map) {
                    JSONObject map = new JSONObject((Map) data);
                    List<String> handleId = StringUtil.isNotEmpty(map.getString("handleId")) ? Arrays.asList(map.getString("handleId").split(",")) : new ArrayList<>();
                    userIds.addAll(handleId);
                }
            }
//            String url = properties.getGetUserUrl();
//            String token = UserProvider.getToken();
//            Map<String,Object> dataMap =new HashMap<>();
//            dataMap.put("taskDefinitionKey",taskDefinitionKey);
//            dataMap.put("applyUserId",applyUserId);
//            dataMap.put("processInstanceId",processInstanceId);
//            dataMap.put("businessKey",businessKey);
//            dataMap.putAll(formDataMap);
//            JSONObject object = HttpUtil.httpRequest(url, "POST", JsonUtil.getObjectToString(dataMap), token);
//            if (object != null && object.get("data") != null) {
//                JSONObject data = object.getJSONObject("data");
//                List<String> handleId = StringUtil.isNotEmpty(data.getString("handleId")) ? Arrays.asList(data.getString("handleId").split(",")) : new ArrayList<>();
//                userIds.addAll(handleId);
//            }
        }
        //【候选人】  //也就是说 选了候选人员, 但是前台没有传值? 目前应该进不来这个if
        else if (FlowTaskOperatorEnum.Candidate.getCode().equals(assigneeType)) {
//            userIds.addAll(properties.getApprovers());
//            List<String> list = new ArrayList<>();
//            list.addAll(properties.getApproverPos());
//            list.addAll(properties.getApproverRole());
//            list.addAll(properties.getApproverOrg());
//            list.addAll(properties.getApproverGroup());
//            List<UserRelationEntity> listByObjectIdAll = serviceAllUtil.getListByObjectIdAll(list);
//            List<String> userPosition = listByObjectIdAll.stream().map(UserRelationEntity::getUserId).collect(Collectors.toList());
//            userIds.addAll(userPosition);
        }
        else if(FlowTaskOperatorEnum.DEPT_CONTROL_DEPT_LEADER.getCode().equals(assigneeType)){
            //
            //获取到节点上的数据传递

            Object data = formDataMap.get(properties.getFormField());
            if (data != null) {
                List<String> list = new ArrayList<>();
                try {
                    list.addAll(JsonUtil.getJsonToList(String.valueOf(data), String.class));
                } catch (Exception e) {

                }
                if (data instanceof List) {
                    list.addAll((List) data);
                } else {
                    list.addAll(Arrays.asList(String.valueOf(data).split(",")));
                }
                List<String> id = new ArrayList<>();
                for (String s : list) {
                    id.add(s.split("--")[0]);
                }
                id=CollUtil.distinct(id);
                //
                String formFieldType = properties.getFormFieldType();
                //
                if("1".equals(formFieldType)){
                    List<UserEntity> userName = serviceAllUtil.getUserName(id);
                    if(CollUtil.isNotEmpty(userName)){
                        for (UserEntity entity : userName) {
                            String managerId = entity.getManagerId();
                            if(StringUtils.isNotBlank(managerId)){
                                userIds.add(managerId);
                            }
                        }
                    }
                }
                else if("2".equals(formFieldType)){
                    List<OrganizeEntity> organizeName = serviceAllUtil.getOrganizeName(id);
                    if(CollUtil.isNotEmpty(organizeName)){
                        for (OrganizeEntity organizeEntity : organizeName) {
                            String managerId = organizeEntity.getManagerId();
                            if(StringUtils.isNotBlank(managerId)){
                                userIds.add(managerId);
                            }
                        }
                    }
                }
            }
        }
        //【指定人】
        else if (FlowTaskOperatorEnum.Nominator.getCode().equals(assigneeType)) {
            List<String> list = new ArrayList<>();
            if(flowElement instanceof CallActivity || flowElement instanceof ManualTask){
                list.addAll(properties.getInitiator());
            }
            else{
                list.addAll(properties.getApprovers());
            }
            List<String> handleIdAll = serviceAllUtil.getUserListAll(list);
            userIds.addAll(handleIdAll);

            Integer extraRule = properties.getExtraRule();
            //附加规则
            rule(userIds,applyUserId,extraRule);
        }
        else if(FlowTaskOperatorEnum.HISTORY_NODE_ASSIGNEE.getCode().equals(assigneeType)){
            String nodeId = properties.getNodeId();
            if(StringUtils.isNotBlank(nodeId)){
                List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().taskDefinitionKey(nodeId).orderByTaskCreateTime().desc().listPage(0, 1);
                if(CollUtil.isNotEmpty(historicTaskInstances)){
                    HistoricTaskInstance historicTaskInstance = historicTaskInstances.get(0);
                    String executionId = historicTaskInstance.getExecutionId();
                    HistoricVariableInstance historicVariableInstance = historyService.createHistoricVariableInstanceQuery().processInstanceId(historicTaskInstance.getProcessInstanceId()).variableName(nodeId + "assigneeList").singleResult();
                    if(historicVariableInstance!=null){
                        List<String> value = (List<String>) historicVariableInstance.getValue();
                        userIds.addAll(value);
                    }
                }
            }
        }
        Iterator<String> stringIterator = userIds.iterator();
        while (stringIterator.hasNext()){
            String next = stringIterator.next();
            if(StringUtils.isBlank(next)){
                stringIterator.remove();
            }
        }
        //第一次去重
        ArrayList<String> distinct = CollUtil.distinct(userIds);

        if(CollUtil.isEmpty(distinct)){
            return distinct;
        }
        else{
            //统一 去查询有没有 流程委托 ,
            Date now = new Date();
            LambdaQueryWrapper<FlowDelegateEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.in(FlowDelegateEntity::getCreatorUserId,userIds);
            lambdaQueryWrapper.eq(FlowDelegateEntity::getType,1);
            lambdaQueryWrapper.le(FlowDelegateEntity::getStartTime,now);
            lambdaQueryWrapper.ge(FlowDelegateEntity::getEndTime,now);
            lambdaQueryWrapper.orderByAsc(FlowDelegateEntity::getCreatorTime);
            List<FlowDelegateEntity> list = flowDelegateService.list(lambdaQueryWrapper);
            List<FlowDelegateEntity> finalUserList= new LinkedList<>();
            if(CollUtil.isNotEmpty(list)){
                for (FlowDelegateEntity flowDelegateEntity : list) {
                    String dbFlowId = flowDelegateEntity.getFlowId();
                    if(StringUtils.isBlank(dbFlowId)){
                        finalUserList.add(flowDelegateEntity);
                    }
                    else if(flowId.equals(dbFlowId)){
                        finalUserList.add(flowDelegateEntity);
                    }
                    else if(dbFlowId.contains(flowId)){
                        finalUserList.add(flowDelegateEntity);
                    }
                }

                if(CollUtil.isNotEmpty(finalUserList)){
                    Map<String,String> flowDelegateEntityMap = new HashMap<>();
                    for (FlowDelegateEntity flowDelegateEntity : finalUserList) {
                        flowDelegateEntityMap.put(flowDelegateEntity.getUserId(),flowDelegateEntity.getToUserId());
                    }
                    //进行流程委托替换
                    Iterator<String> iterator = distinct.iterator();
                    List<String> goOutList=new ArrayList<>();
                    while (iterator.hasNext()){
                        String next = iterator.next();
                        String assigneeUserId = MapUtil.getStr(flowDelegateEntityMap,next);
                        iterator.remove();
                        goOutList.add(assigneeUserId);
                    }
                    distinct.addAll(goOutList);
                }
            }
            ArrayList<String> finalUserIdList = CollUtil.distinct(distinct);

            return finalUserIdList;
        }

    }

    private void getManageOrgContinueByLevel(String organizeId, Integer level,List<String> deptLeaderList,String noLeaderFlag,String breakFlag) {
        if("2".equals(breakFlag)){
            --level;
            if (level == 0) {
                OrganizeEntity organizeInfo = serviceAllUtil.getOrganizeInfo(organizeId);
                if(organizeInfo!=null ){
                    if(StringUtils.isNotBlank(organizeInfo.getManagerId())){
                        deptLeaderList.addAll(Arrays.asList(organizeInfo.getManagerId().split(",")));
                    }
                }
            } else {
                OrganizeEntity organizeInfo = serviceAllUtil.getOrganizeInfo(organizeId);
                if(organizeInfo!=null ){
                    if(StringUtils.isNotBlank(organizeInfo.getManagerId())){
                        deptLeaderList.add(organizeInfo.getManagerId());
                        getManageOrgContinueByLevel(organizeInfo.getParentId(),level,deptLeaderList,noLeaderFlag,breakFlag);
                    }
                    else{
                        if("0".equals(noLeaderFlag)){
                            breakFlag="1";//退出递归
                        }
                        else{
                            getManageOrgContinueByLevel(organizeInfo.getParentId(),level,deptLeaderList,noLeaderFlag,breakFlag);
                        }
                    }
                }
            }
        }
    }

    public   List<String> getCallActivityAssignUserList(Properties properties, Map<String,String> taskInfoMap, String flowId,Map<String,Object> formDataMap) {
        String processDefinitionId = MapUtil.getStr(taskInfoMap, "processDefinitionId");
        String taskDefinitionKey = MapUtil.getStr(taskInfoMap, "taskDefinitionKey");
        String processInstanceId = MapUtil.getStr(taskInfoMap, "processInstanceId");
        String businessKey = MapUtil.getStr(taskInfoMap, BUSINESS_KEY);
        String applyUserId = MapUtil.getStr(taskInfoMap, APPLY_USER_ID);
        List<String> userIds=new ArrayList<>();
        Integer assigneeType = properties.getAssigneeType();
        //发起者【发起者主管】
        if (FlowTaskOperatorEnum.LaunchCharge.getCode().equals(assigneeType)) {
            UserEntity info = serviceAllUtil.getUserInfo(applyUserId);
            if (info != null) {
                userIds.add(getManagerByLevel(info.getManagerId(), properties.getManagerLevel()));
            }
        }
        //发起者【部门主管】
        else if (FlowTaskOperatorEnum.DepartmentCharge.getCode().equals(assigneeType)) {
            UserEntity userEntity = serviceAllUtil.getUserInfo(applyUserId);
            if (userEntity != null) {
                OrganizeEntity organizeEntity = getManageOrgByLevel(userEntity.getOrganizeId(), properties.getDepartmentLevel());
                if (organizeEntity != null) {
                    userIds.add(organizeEntity.getManagerId());
                }
            }
        }
        //【发起本人】
        else if (FlowTaskOperatorEnum.InitiatorMe.getCode().equals(assigneeType)) {
            userIds.add(applyUserId);
        }
        //【环节】
        else if (FlowTaskOperatorEnum.Tache.getCode().equals(assigneeType)) {
            //此有歧义 留给后续产品经理探讨
            String nodeId = properties.getNodeId();
            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
            Process mainProcess = bpmnModel.getMainProcess();
            UserTask targetNode = (UserTask) bpmnModel.getFlowElement(nodeId);
            String property = getAttributeValueByTaskDefinitionKey(mainProcess, targetNode.getId(), "userTask");
            Properties targetNodeProperty = JSONObject.parseObject(property, new TypeReference<Properties>() {
            });
            taskInfoMap.put("taskDefinitionKey",targetNode.getId());
            List<String> assignUserList = getAssignUserList(targetNodeProperty, taskInfoMap, flowId,formDataMap);
            userIds.addAll(assignUserList);
        }
        //【变量】
        else if (FlowTaskOperatorEnum.Variate.getCode().equals(assigneeType)) {
            //获取到节点上的数据传递

            Object data = formDataMap.get(properties.getFormField());
            if (data != null) {
                List<String> list = new ArrayList<>();
                try {
                    list.addAll(JsonUtil.getJsonToList(String.valueOf(data), String.class));
                } catch (Exception e) {

                }
                if (data instanceof List) {
                    list.addAll((List) data);
                } else {
                    list.addAll(Arrays.asList(String.valueOf(data).split(",")));
                }
                List<String> id = new ArrayList<>();
                for (String s : list) {
                    id.add(s.split("--")[0]);
                }
                List<UserRelationEntity> listByObjectIdAll = serviceAllUtil.getListByObjectIdAll(id);
                List<String> userPosition = listByObjectIdAll.stream().map(UserRelationEntity::getUserId).collect(Collectors.toList());
                List<String> handleIdAll = new ArrayList<>();
                handleIdAll.addAll(userPosition);
                handleIdAll.addAll(id);
                userIds.addAll(handleIdAll);
            }
        }
        //【服务】
        else if (FlowTaskOperatorEnum.Serve.getCode().equals(assigneeType)) {
//            String url = properties.getGetUserUrl();
//            String token = UserProvider.getToken();
//            Map<String,Object> dataMap =new HashMap<>();
//            dataMap.put("taskDefinitionKey",taskDefinitionKey);
//            dataMap.put("applyUserId",applyUserId);
//            dataMap.put("processInstanceId",processInstanceId);
//            dataMap.put("businessKey",businessKey);
//            dataMap.putAll(formDataMap);
//            JSONObject object = HttpUtil.httpRequest(url, "POST", JsonUtil.getObjectToString(dataMap), token);
//            if (object != null && object.get("data") != null) {
//                JSONObject data = object.getJSONObject("data");
//                List<String> handleId = StringUtil.isNotEmpty(data.getString("handleId")) ? Arrays.asList(data.getString("handleId").split(",")) : new ArrayList<>();
//                userIds.addAll(handleId);
//            }
        }
        //【候选人】  //也就是说 选了候选人员, 但是前台没有传值? 目前应该进不来这个if
        else if (FlowTaskOperatorEnum.Candidate.getCode().equals(assigneeType)) {
//            userIds.addAll(properties.getApprovers());
//            List<String> list = new ArrayList<>();
//            list.addAll(properties.getApproverPos());
//            list.addAll(properties.getApproverRole());
//            list.addAll(properties.getApproverOrg());
//            list.addAll(properties.getApproverGroup());
//            List<UserRelationEntity> listByObjectIdAll = serviceAllUtil.getListByObjectIdAll(list);
//            List<String> userPosition = listByObjectIdAll.stream().map(UserRelationEntity::getUserId).collect(Collectors.toList());
//            userIds.addAll(userPosition);
        }
        //【指定人】
        else if (FlowTaskOperatorEnum.Nominator.getCode().equals(assigneeType)) {
            List<String> list = new ArrayList<>();
            list.addAll(properties.getApprovers());
            List<String> handleIdAll = serviceAllUtil.getUserListAll(list);
            userIds.addAll(handleIdAll);

            Integer extraRule = properties.getExtraRule();
            //附加规则
            rule(userIds,applyUserId,extraRule);
        }

        Iterator<String> stringIterator = userIds.iterator();
        while (stringIterator.hasNext()){
            String next = stringIterator.next();
            if(StringUtils.isBlank(next)){
                stringIterator.remove();
            }
        }
        //第一次去重
        ArrayList<String> distinct = CollUtil.distinct(userIds);

        if(CollUtil.isEmpty(distinct)){
            return distinct;
        }
        else{
            //统一 去查询有没有 流程委托 ,
            Date now = new Date();
            LambdaQueryWrapper<FlowDelegateEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
            lambdaQueryWrapper.in(FlowDelegateEntity::getCreatorUserId,userIds);
            lambdaQueryWrapper.eq(FlowDelegateEntity::getType,1);
            lambdaQueryWrapper.le(FlowDelegateEntity::getStartTime,now);
            lambdaQueryWrapper.ge(FlowDelegateEntity::getEndTime,now);
            lambdaQueryWrapper.orderByAsc(FlowDelegateEntity::getCreatorTime);
            List<FlowDelegateEntity> list = flowDelegateService.list(lambdaQueryWrapper);
            List<FlowDelegateEntity> finalUserList= new LinkedList<>();
            if(CollUtil.isNotEmpty(list)){
                for (FlowDelegateEntity flowDelegateEntity : list) {
                    String dbFlowId = flowDelegateEntity.getFlowId();
                    if(StringUtils.isBlank(dbFlowId)){
                        finalUserList.add(flowDelegateEntity);
                    }
                    else if(flowId.equals(dbFlowId)){
                        finalUserList.add(flowDelegateEntity);
                    }
                    else if(dbFlowId.contains(flowId)){
                        finalUserList.add(flowDelegateEntity);
                    }
                }

                if(CollUtil.isNotEmpty(finalUserList)){
                    Map<String,String> flowDelegateEntityMap = new HashMap<>();
                    for (FlowDelegateEntity flowDelegateEntity : finalUserList) {
                        flowDelegateEntityMap.put(flowDelegateEntity.getUserId(),flowDelegateEntity.getToUserId());
                    }
                    //进行流程委托替换
                    Iterator<String> iterator = distinct.iterator();
                    List<String> goOutList=new ArrayList<>();
                    while (iterator.hasNext()){
                        String next = iterator.next();
                        String assigneeUserId = MapUtil.getStr(flowDelegateEntityMap,next);
                        iterator.remove();
                        goOutList.add(assigneeUserId);
                    }
                    distinct.addAll(goOutList);
                }
            }
            ArrayList<String> finalUserIdList = CollUtil.distinct(distinct);

            return finalUserIdList;
        }

    }

    public static void rule(List<String> userIdAll, String applyUserId, int rule) {
        ServiceAllUtil allUtil = SpringContextHolder.getBean(ServiceAllUtil.class);
        List<Integer> ruleList = ImmutableList.of(FlowExtraRuleEnum.organize.getCode(), FlowExtraRuleEnum.position.getCode(),
                FlowExtraRuleEnum.manager.getCode(), FlowExtraRuleEnum.subordinate.getCode(), FlowExtraRuleEnum.department.getCode());
        if (ruleList.contains(rule)) {
//            FlowUserEntity flowUser = flowUserService.getTaskInfo(taskId);
            UserEntity userInfo = allUtil.getUserInfo(applyUserId);
                List<UserEntity> userList = allUtil.getUserName(userIdAll, true);
                List<String> userListAll = userList.stream().map(UserEntity::getId).collect(Collectors.toList());
                Map<String, List<UserRelationEntity>> relationUserList = allUtil.getListByUserIdAll(userListAll).stream().filter(t -> StringUtil.isNotEmpty(t.getObjectId())).collect(Collectors.groupingBy(UserRelationEntity::getObjectId));
                //附加条件
                switch (FlowExtraRuleEnum.getByCode(rule)) {
                    case organize:
                        List<String> organize = new ArrayList<>();
                        organize.addAll(relationUserList.get(userInfo.getOrganizeId()) != null ? relationUserList.get(userInfo.getOrganizeId()).stream().map(UserRelationEntity::getUserId).collect(Collectors.toList()) : new ArrayList<>());
                        userIdAll.retainAll(organize);
                        break;
                    case position:
                        List<String> position = new ArrayList<>();
                        position.addAll(relationUserList.get(userInfo.getPositionId()) != null ? relationUserList.get(userInfo.getPositionId()).stream().map(UserRelationEntity::getUserId).collect(Collectors.toList()) : new ArrayList<>());
                        userIdAll.retainAll(position);
                        break;
                    case manager:
                        List<String> manager = new ArrayList<>();
                        manager.add(userInfo.getManagerId());
                        userIdAll.retainAll(manager);
                        break;
                    case subordinate:
                        List<String> subordinate = new ArrayList<>();
                        String listByManagerId = allUtil.getListByManagerId(userInfo.getId()).stream().map(UserEntity::getId).collect(Collectors.joining(","));
                        subordinate.addAll(StringUtil.isNotEmpty(listByManagerId) ? new ArrayList<>(Arrays.asList(listByManagerId.split(","))) : new ArrayList<>());
                        userIdAll.retainAll(subordinate);
                        break;
                    case department:
                        List<String> department = new ArrayList<>();
                        List<String> departmentAll = allUtil.getDepartmentAll(userInfo.getOrganizeId()).stream().map(OrganizeEntity::getId).collect(Collectors.toList());
                        for (String id : departmentAll) {
                            department.addAll(relationUserList.get(id) != null ? relationUserList.get(id).stream().map(UserRelationEntity::getUserId).collect(Collectors.toList()) : new ArrayList<>());
                        }
                        userIdAll.retainAll(department);
                        break;
                    default:
                        break;
                }

        }
    }


    /**
     * 递归主管
     *
     * @param managerId 主管id
     * @param level     第几级
     * @return
     */
    public String getManagerByLevel(String managerId, long level) {
        --level;
        if (level == 0) {
            return managerId;
        } else {
            UserEntity userEntity = serviceAllUtil.getUserInfo(managerId);
            return userEntity != null ? getManagerByLevel(userEntity.getManagerId(), level) : "";
        }
    }

    public void getManagerContinueByLevel(String managerId, long level,List<String> list) {
        --level;
        if (level == 0) {
            if(StringUtils.isNotBlank(managerId)){
                list.add(managerId);
            }
        } else {
            if(StringUtils.isNotBlank(managerId)){
                list.add(managerId);
            }
            UserEntity userEntity = serviceAllUtil.getUserInfo(managerId);
            if(userEntity != null ){
                getManagerContinueByLevel(userEntity.getManagerId(), level,list);
            }
        }
    }





}
























































































































































































































































































































































































































































































































































